package com.yc.spring.aop.自定义Mybatis;

import com.yc.spring.bank.bean.Account;
import com.yc.spring.bank.dao.AccountDao;
import org.apache.ibatis.annotations.Insert;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SqlSession {

    public <T> T getMapper(Class<T> cls) {
        T proxy = (T) Proxy.newProxyInstance(cls.getClassLoader(),
                new Class[]{cls},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 获取方法上的注解
                        Insert insert = method.getAnnotation(Insert.class);
                        if (insert != null) {
                            // 执行查询
                            String sql = insert.value()[0];
                            // 多个参数的判断
                            if (args.length > 1
                                    || args[0] instanceof Collection
                                    || !args[0].getClass().isPrimitive()
                                    || !(args[0] instanceof String)) {
                                // 多参数
                                // 约定 args[0] 是一个对象
                                // select * from bank_account where id=#{id}
                                // DBHelper.select()
                                // 正则表达式
                                // 构建正则表达式对象  ==>　js. RegExp
                                Pattern pattern = Pattern.compile("#\\{(\\w+)}");
                                Matcher matcher = pattern.matcher(sql);
                                int index = 0; // 开始查找的位置
                                List<Object> plist = new ArrayList<>();
                                while (matcher.find(index)) {
                                    // 如果找到了一个参数，进入循环
                                    String paramName = matcher.group(1);
                                    // 根据参数名获取  类属性对象
                                    Field f = args[0].getClass().getDeclaredField(paramName);
                                    // 设置强制访问
                                    f.setAccessible(true);
                                    // 获取属性值
                                    Object value = f.get(args[0]);
                                    // 添加到参数集合
                                    plist.add(value);
                                    // 设置查找起始字符位置，到当前捕获的字符串结束的位置
                                    index = matcher.end();
                                }
                                sql = sql.replaceAll("#\\{\\w+}", "?");

                                System.out.println(sql);
                                System.out.println(plist);
                                // 最后执行 DBHelper.update(sql, plist.toArray())
                                // update(String sql, Object ...params)
                            } else {
                                // 单参数
                            }
                        } else {
                            // 执行增删改
                        }
                        return null;
                    }
                });
        return proxy;
    }

    public static void main(String[] args) {
        SqlSession sqlSession = new SqlSession();
        AccountDao mapper = sqlSession.getMapper(AccountDao.class);
        mapper.selectById(1);
        Account account = new Account();
        account.setId(123456);
        account.setName("张三");
        account.setMoney(2000d);
        mapper.insert(account);
    }
}
